package cn.wp.ewallet.upms.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.wp.common.core.authentication.AuthenticationInfo;
import cn.wp.common.core.authentication.UsernamePasswordToken;
import cn.wp.common.core.dto.WpResult;
import cn.wp.common.core.exception.WpAuthenticationException;
import cn.wp.common.core.id.Id;
import cn.wp.common.core.model.WpState;
import cn.wp.common.core.module.login.GenericLoginService;
import cn.wp.common.core.module.login.LoginService;
import cn.wp.common.core.plugin.verification.VerificationCodeService;
import cn.wp.common.core.util.BCryptPasswordEncoder;
import cn.wp.common.core.util.IpUtil;
import cn.wp.common.core.web.WpWebContext;
import cn.wp.ewallet.common.model.EwalletAuthenticationInfo;
import cn.wp.ewallet.upms.dao.BsRoleInfoDao;
import cn.wp.ewallet.upms.dao.LoginLogDao;
import cn.wp.ewallet.upms.dao.PaObjectRoleRelDao;
import cn.wp.ewallet.upms.dao.PaUserInfoDao;
import cn.wp.ewallet.upms.model.entity.BsRoleInfoDo;
import cn.wp.ewallet.upms.model.entity.LoginLogDo;
import cn.wp.ewallet.upms.model.entity.PaObjectRoleRelDo;
import cn.wp.ewallet.upms.model.entity.PaUserInfoDo;
import cn.wp.ewallet.upms.service.WalletLoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service("appLoginService")
@Slf4j
public class WalletAppLoginServiceImpl extends GenericLoginService implements WalletLoginService {

    @Autowired
    private LoginLogDao loginLogDao;

    @Autowired
    private PaUserInfoDao paUserInfoDao;

    @Autowired
    private BsRoleInfoDao bsRoleInfoDao;

    @Autowired
    private PaObjectRoleRelDao paObjectRoleRelDao;

    @Autowired
    private VerificationCodeService verificationCodeService;

    @Autowired
    @Qualifier("appLoginService")
    private WalletAppLoginServiceImpl appLoginService;

    @Override
    public UsernamePasswordToken createUsernamePasswordToken(String phone) {
        List<PaUserInfoDo> paUserInfoDoList = paUserInfoDao.selectPaUserInfoByPhone(phone);
        String encodePass = BCryptPasswordEncoder.getInstance().encode("111");
        // 此处对“111”加密，为了匹配controller输入的密码
        return new UsernamePasswordToken(phone,encodePass);
    }

    @Override
    public AuthenticationInfo loadUserByUsername(String phone) {
        // 验证码校验
        String code = WpWebContext.getRequest().getParameter("code");
        String mobilePrefix = WpWebContext.getRequest().getParameter("mobilePrefix");
        if (StrUtil.isNotBlank(code)) {
            /*boolean check = verificationCodeService.checkCode(phone,code);
            if (!check) {
                throw new WpAuthenticationException(1001, "验证码错误");
            }*/

            WpState wpState = verificationCodeService.checkCodeState(phone,code);
            if(wpState.getCode()  > 0){
                throw new WpAuthenticationException(wpState.getCode(),wpState.getMessage());
            }
        }

        EwalletAuthenticationInfo authenticationInfo = new EwalletAuthenticationInfo();
        List<PaUserInfoDo> paUserInfoDoList = paUserInfoDao.selectPaUserInfoByPhone(phone);
        if (paUserInfoDoList.size() == 0) {
            log.info("手机号[{}]未注册，开始注册 = " + phone);
            // 解决 this调用 事务失效问题
            //WalletAppLoginServiceImpl proxy =(WalletAppLoginServiceImpl) AopContext.currentProxy();
            AuthenticationInfo info = appLoginService.createPaUserInfoByPhone(phone,mobilePrefix);
            return info;
        } else {
            PaUserInfoDo paUserInfoDo = paUserInfoDoList.get(0);
            authenticationInfo.setId(paUserInfoDo.getUserId());
            authenticationInfo.setPhone(phone);
            //PaObjectRoleRelDo paObjectRoleRelDo = paObjectRoleRelDao.selecPaObjectRoleRelByUserId(paUserInfoDo.getUserId());
            //String roleId = paObjectRoleRelDo.getRoleId();
            //ArrayList<String> roleIds = new ArrayList<>();
            //roleIds.add(roleId);
            //authenticationInfo.setRoleIds(roleIds);
            return authenticationInfo;
        }
    }

    @Override
    public void onLoginSuccess(AuthenticationInfo authenticationInfo) {
        log.info("[ " + authenticationInfo.getPhone() + " ]登录成功");
        String uuid = WpWebContext.getRequest().getHeader("uuid");
        LoginLogDo loginLogDo = new LoginLogDo();
        loginLogDo.setLogId(Id.gen());
        if (authenticationInfo.getPhone() != null) {
            loginLogDo.setAccountNo(authenticationInfo.getPhone());
        } else {
            loginLogDo.setAccountNo(authenticationInfo.getAccount());
        }
        loginLogDo.setIpAddress(IpUtil.getIpAddress(WpWebContext.getRequest()));
        loginLogDo.setIsSuccess(0);
        loginLogDo.setLoginTime(DateUtil.date());
        loginLogDo.setImeiNo(uuid);
        loginLogDao.insertLoginLog(loginLogDo);

        // 最后登录设备添加到缓存
        loginLogDao.insertLoginEquipment(authenticationInfo.getAccount(), uuid);
    }

    @Override
    public void onLoginFailure(String phone, WpAuthenticationException ex) {
        log.error("[ " + phone + " ]登录失败,原因：" + ex.getMessage());
        LoginLogDo loginLogDo = new LoginLogDo();
        loginLogDo.setLogId(Id.gen());
        loginLogDo.setAccountNo(phone);
        loginLogDo.setIpAddress(IpUtil.getIpAddress(WpWebContext.getRequest()));
        loginLogDo.setIsSuccess(1);
        loginLogDo.setLoginTime(DateUtil.date());
        loginLogDo.setImeiNo(WpWebContext.getRequest().getHeader("uuid"));
        loginLogDo.setFailCause(ex.getMessage());
        loginLogDao.insertLoginLog(loginLogDo);
    }

    @Override
    public void onLogoutSuccess(AuthenticationInfo authenticationInfo) {
        System.err.println("注销登录成功");
    }

    @Transactional
    public AuthenticationInfo createPaUserInfoByPhone(String phone,String mobilePrefix) {
        //创建app 用户
        PaUserInfoDo paUserInfo = new PaUserInfoDo();
        paUserInfo.setUserId(Id.gen());
        paUserInfo.setHeadPhotoAddress("");
        paUserInfo.setLoginPwd("");
        paUserInfo.setUserNikename("");
        paUserInfo.setUserTel(phone);
        paUserInfo.setMobilePrefix(mobilePrefix);
        paUserInfo.setCreateDate(new Date());
        paUserInfoDao.insertPaUserInfo(paUserInfo);

        //创建角色
        /*BsRoleInfoDo bsRoleInfoDo = new BsRoleInfoDo();
        bsRoleInfoDo.setRoleId(Id.gen());
        bsRoleInfoDo.setRoleName("");
        bsRoleInfoDo.setRoleDesc("");
        bsRoleInfoDo.setRoleType("2000");
        bsRoleInfoDo.setCreateDate(new Date());
        bsRoleInfoDo.setCreateUser(paUserInfo.getUserId());
        bsRoleInfoDao.insertBsRoleInfo(bsRoleInfoDo);*/

        AuthenticationInfo authenticationInfo = new AuthenticationInfo();
        authenticationInfo.setId(paUserInfo.getUserId());
        authenticationInfo.setPhone(phone);
        /*List<String> roleIds = new ArrayList<>();
        roleIds.add(bsRoleInfoDo.getRoleId());
        authenticationInfo.setRoleIds(roleIds);*/
        return authenticationInfo;
    }


    @Override
    public WpResult modifyPassword(String oldPassword, String newPassword) {
        throw new RuntimeException("移动端修改密码方法暂未实现");
    }

}